package com.secsbrain.cmdb.web.controller;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.secsbrain.cmdb.biz.IHostService;
import com.secsbrain.common.utils.DateTimeUtils;
import com.secsbrain.sso.core.SsoHelper;
import com.secsbrain.cmdb.dal.model.Host;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.plugins.Page;
import com.secsbrain.cmdb.biz.impl.CommonService;
import com.secsbrain.cmdb.biz.utils.ExcelExportUtil;
import com.secsbrain.common.ErrorCodeEnum;
import com.secsbrain.common.ResponseResult;
import com.secsbrain.cmdb.web.dto.HostBrief;

/**
 * 主机控制层
 * @author zhaoyi
 *
 */
@RestController
@RequestMapping("api/host")
public class HostController{
	
    @Autowired
    IHostService hostService;
    
    @Autowired
    CommonService commonService;
    
	/**
	 * @api {GET} /api/host/list  查询主机列表
	 * 
	 * @apiGroup HOST
	 * @apiParam {Number{11}} [idcId]     	   机房id
	 * @apiParam {String{5}}  [type]      	   主机类型
	 * @apiParam {String{5}}  [clusterName]  集群
	 * @apiParam {String{20}} [ip]        	   内(公)网IP
	 * @apiParam {String{20}} [hostName]     主机名
	 * @apiParam {String{10}} [env]          应用环境
	 * @apiParam {String{20}} [relativeHost] 宿主机
	 * @apiParam {String{20}} [purpose]      主机功能
	 * 
	 * @apiSuccess {Object[]} data           	 数据列表
	 * @apiSuccess {Number} data.id           	主机ID
	 * @apiSuccess {String} data.clusterName    集群
	 * @apiSuccess {String} data.creator      	创建人
	 * @apiSuccess {String} data.updator      	更新人
	 * @apiSuccess {String} data.createTimeStr  创建时间
	 * @apiSuccess {String} data.updateTimeStr  更新时间
	 * @apiSuccess {String} data.kernel  		系统内核，如Linux 
	 * @apiSuccess {String} data.kernelRelease  系统内核版本，如4.9.0-deepin9-amd64
	 * @apiSuccess {String} data.type  			设备类型，如VMware
	 * @apiSuccess {String} data.hostName  		主机唯一标识
	 * @apiSuccess {String} data.ip  			ip，如[10.0.0.16]，多个以,分隔
	 * @apiSuccess {String} data.host  			主机名，如kira-PC
	 * @apiSuccess {String} data.os  			操作系统，如Deepin
	 * @apiSuccess {String} data.osrelease  	操作系统版本，如('15.4.1',)
	 * @apiSuccess {String} data.saltversion  	Salt版本，如2017.7.2
	 * @apiSuccess {String} data.systemSerialnumber   SN号
	 * @apiSuccess {Number} data.numCpus  		CPU数量
	 * @apiSuccess {String} data.cpuModel  		CPU型号
	 * @apiSuccess {String} data.productname  	服务器型号，如VMware Virtual Platform
	 * @apiSuccess {String} data.osarch  		系统架构，如x86_64
	 * @apiSuccess {String} data.cpuarch  		CPU架构
	 * @apiSuccess {Number} data.memTotal  		内存大小，如7969
	 * @apiSuccess {Number} data.minionStatus  	Minion状态
	 * @apiSuccess {Number} data.delStatus  	删除状态  0-未删除，1-删除
	 * @apiSuccess {Number} data.cabinetId  	机柜ID
	 * @apiSuccess {String} data.cabinetName  	机柜名称
	 * @apiSuccess {Number} data.idcId  		机房ID
	 * @apiSuccess {String} data.rackName  		机房名称
	 * @apiSuccess {String} data.groupName  	部署分组
	 * @apiSuccess {Number} data.diskCapacity   磁盘容量
	 * @apiSuccess {String} data.env  			应用环境 
	 * @apiSuccess {String} data.comment  		备注
	 * @apiSuccess {String} data.ipPublic  		公网ip
	 * @apiSuccess {String} data.purpose  		用途
	 * @apiSuccess {String} data.manager  		负责人 
	 * @apiSuccess {String} data.relativeHost 	关联主机名
     * @apiSuccess {Number} data.istatus   		状态：0闲置，1在用，2故障，3报废
	 * @apiSuccess {Date} data.purchaseDate 	采购日期
	 * @apiSuccess {Date} data.periodDate 		保修到期
	 * @apiSuccess {String} data.assetNumber  	固定资产编号
	 * @apiSuccess {String} data.udesc  		U数 
	 * @apiSuccess {String} data.manager  		负责人 
	 * @apiSuccess {String} data.relativeHost 	关联主机名
	 * @apiSuccess {String} data.configure      主机配置，如1c/1.96g/40g
	 * @apiSuccess {String} data.osNew          操作系统+版本
   	 * 
   	 */
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public ResponseResult<?> queryList(Integer page, Integer limit, Host params) {
    	Page<Host> pageBean=new Page<Host>(page, limit);
    	Page<Host> pageResult=hostService.queryHostPageList(pageBean, params);
    	
    	Map<Long, String> idcMap=commonService.getIdcMap();
    	Map<Long, String> cabinetMap=commonService.getCabinetMap();
    	for(Host host:pageResult.getRecords()){
    		this.parseHost(host, idcMap, cabinetMap);
    	}
    	return new ResponseResult(pageResult);
    }
    
    
    /**
   	 * @api {GET} /api/host/queryHostByCluster  通过集群查询主机信息列表
   	 * 
   	 * @apiGroup HOST
   	 * 
   	 * @apiParam {String{5}}  clusterName  集群
   	 * 
   	 * @apiSuccess {Object[]} data           	主机信息列表
   	 * @apiSuccess {Number} data.hostId         主机ID
	 * @apiSuccess {String} data.saltHost    	主机唯一标识
	 * @apiSuccess {String} data.hostName    	主机名
	 * @apiSuccess {Boolean} data.physical    	是否是物理机
	 * @apiSuccess {String} data.relativeHost   虚拟机所对应物理机唯一标识
     */
	@RequestMapping(value = "/queryHostByCluster", method = RequestMethod.GET)
	public ResponseResult<?> queryHostByCluster(String clusterName) {
		Assert.hasText(clusterName, "clusterName不能为空");
		
	   	Host params=new Host();
	   	params.setClusterName(clusterName);
	   	params.setDelStatus(0);
	   	List<Host> hostList=hostService.selectList(params);
	   	
	   	List<HostBrief> resultList=new ArrayList<HostBrief>();
	   	for(Host host:hostList){
	   		HostBrief hostBrief=new HostBrief();
	   		hostBrief.setHostId(host.getId());
	   		hostBrief.setHostName(host.getHost());
	   		hostBrief.setPhysical("physical".equals(host.getType()));
	   		hostBrief.setRelativeHost(host.getRelativeHost());
	   		hostBrief.setSaltHost(host.getHostName());
	   		resultList.add(hostBrief);
	   	}
	   	return new ResponseResult(resultList);
	}
    
    private void parseHost(Host host,Map<Long, String> idcMap,Map<Long, String> cabinetMap){
    	if(host.getIdcId()!=null&&host.getIdcId()!=0){
			host.setRackName(idcMap.get(host.getIdcId()));
		}
		if(host.getCabinetId()!=null&&host.getCabinetId()!=0){
			host.setCabinetName(cabinetMap.get(host.getCabinetId()));
		}
    	host.setCreateTimeStr(DateTimeUtils.parseDateAsString(host.getCreateTime(), "yyyy-MM-dd HH:mm:ss"));
		host.setUpdateTimeStr(DateTimeUtils.parseDateAsString(host.getUpdateTime(), "yyyy-MM-dd HH:mm:ss"));
		String memTotal=BigDecimal.valueOf(Double.valueOf(host.getMemTotal())).divide(
                BigDecimal.valueOf(1024)).setScale(2, RoundingMode.HALF_UP).toString();
		host.setConfigure(host.getNumCpus()+"c/"+subZeroAndDot(memTotal)+"g/"+host.getDiskCapacity()+"g");
		host.setOsNew(host.getOs()+" "+host.getOsrelease());
    }
    
    @RequestMapping("/exportContact")
    public void export(HttpServletResponse response,HttpServletRequest request,Host params) {
    	Page<Host> pageBean=new Page<Host>(1, 10000);
		params.setEnv(null);
    	if(StringUtils.isNotEmpty(params.getAppEnv())){
    		params.setEnv(params.getAppEnv());
    	}
    	Page<Host> pageResult=hostService.queryHostPageList(pageBean, params);
        
    	List<Host> list = pageResult.getRecords();

    	ExcelExportUtil e  =   new  ExcelExportUtil();
	    e.createRow( 0 );
        e.setCell( 0 ,  "主机" );
        e.setCell( 1 ,  "主机类型" );
        e.setCell( 2 ,  "内网IP" );
        e.setCell( 3 ,  "公网IP" );
        e.setCell( 4 ,  "主机名" );
        e.setCell( 5 ,  "主机功能" );
        e.setCell( 6 ,  "宿主机" );
        e.setCell( 7 ,  "配置" );
        e.setCell( 8 ,  "机房" );
        e.setCell( 9 ,  "应用环境" );
        e.setCell( 10 ,  "SN序列号" );
        e.setCell( 11 ,  "负责人" );
        e.setCell( 12 ,  "状态" );
        e.setCell( 13 ,  "服务器型号" );
        e.setCell( 14 ,  "采购日期" );
        e.setCell( 15 ,  "保修到期" );
        e.setCell( 16 ,  "操作系统" );
        e.setCell( 17 ,  "机柜" );
        e.setCell( 18 ,  "u数" );
        e.setCell( 19 ,  "kernel版本" );
        e.setCell( 20 ,  "CPU型号" );
        e.setCell( 21 ,  "salt版本" );
        e.setCell( 22 ,  "固定资产编号" );
        e.setCell( 23 ,  "部署分组" );
        e.setCell( 24 ,  "集群" );
        e.setCell( 25 ,  "备注" );
        
        Map<Long, String> idcMap=commonService.getIdcMap();
    	Map<Long, String> cabinetMap=commonService.getCabinetMap();
    	
		if (list != null && list.size() > 0) {
			for (int i =0;i < list.size();i++) {
				Host host = list.get(i);
	    		this.parseHost(host, idcMap, cabinetMap);

				e.createRow( i+1 );
				e.setCell( 0 ,  host.getHostName() );
		        e.setCell( 1 ,  host.getType());
		        e.setCell( 2 ,  host.getIp() );
		        e.setCell( 3 ,  host.getIpPublic() );
		        e.setCell( 4 ,  host.getHost() );
		        e.setCell( 5 ,  host.getPurpose() );
		        e.setCell( 6 ,  host.getRelativeHost() );
		        e.setCell( 7 ,  host.getConfigure() );
		        e.setCell( 8 ,  host.getRackName() );
		        e.setCell( 9 ,  host.getEnv() );
		        e.setCell( 10 , host.getSystemSerialnumber() );
		        e.setCell( 11 ,  host.getManager() );
		        e.setCell( 12 ,  this.getStatusName(host.getIstatus()) );
		        e.setCell( 13 ,  host.getProductname() );
		        e.setCell( 14 ,  DateTimeUtils.parseDateAsString(host.getPurchaseDate(), "yyyy-MM-dd") );
		        e.setCell( 15 ,   DateTimeUtils.parseDateAsString(host.getPeriodDate(), "yyyy-MM-dd") );
		        e.setCell( 16 ,  host.getOsNew() );
		        e.setCell( 17 ,  host.getCabinetName() );
		        e.setCell( 18 ,  host.getUdesc() );
		        e.setCell( 19 ,  host.getKernelRelease() );
		        e.setCell( 20 ,  host.getCpuModel() );
		        e.setCell( 21 ,  host.getSaltversion() );
		        e.setCell( 22 ,  host.getAssetNumber() );
		        e.setCell( 23 ,  host.getGroupName() );
		        e.setCell( 24 ,  host.getClusterName() );
		        e.setCell( 25 ,  host.getComment() );
			}
			
		}
		e.downloadExcel(request, response, "主机统计"+ new SimpleDateFormat("yyyyMMdd").format(new Date())+".xls");
    	
    }
    
    private String getStatusName(Integer status){
    	if(status==0){
    		return "闲置";
    	}else if(status==1){
    		return "在用";
    	}else if(status==2){
    		return "故障";
    	}else if(status==3){
    		return "报废";
    	}
    	return status+"";
    }
    
    /**
     * 使用java正则表达式去掉多余的.与0
     * @param s
     * @return 
     */
    public static String subZeroAndDot(String s){
        if(s.indexOf(".") > 0){
            s = s.replaceAll("0+?$", "");//去掉多余的0
            s = s.replaceAll("[.]$", "");//如最后一位是.则去掉
        }
        return s;
    }
    
    /**
     * 功能描述: <br>
     * 加载服务器
     *
     * @return
     */
    @RequestMapping(value = "/loadServer", method = RequestMethod.GET)
    public ResponseResult<?> loadServer() {
    	try {
			hostService.loadServer(SsoHelper.currentUser().getNickname());
		} catch (Exception e) {
			return new ResponseResult<>(ErrorCodeEnum.ERROR_COMMON_SYSTEM.getCode(), "加载服务器信息失败");
		}
    	return new ResponseResult();
    }
    
    /**
     * 功能描述: <br>
     * 查询所有列表
     *
     * @param params
     * @return
     */
    @RequestMapping(value = "/allList", method = RequestMethod.GET)
    public ResponseResult<?> queryAllList(Host params) {
    	params.setDelStatus(0);
    	List<Host> list=hostService.selectList(params);
    	return new ResponseResult(list);
    }
    
    /**
     * 功能描述: <br>
     * 查询physical主机列表
     *
     * @param params
     * @return
     */
    @RequestMapping(value = "/queryPhysicalList", method = RequestMethod.GET)
    public ResponseResult<?> queryPhysicalList(Host params) {
    	params.setType("physical");
    	params.setDelStatus(0);
    	List<Host> list=hostService.selectList(params);
    	return new ResponseResult(list);
    }
    
    /**
	 * @api {GET} /api/host/queryAllCluster  查询所有集群
	 * 
	 * @apiGroup HOST
	 * 
	 * @apiSuccess {String[]} data           	集群列表
     */
    @RequestMapping(value = "/queryAllCluster", method = RequestMethod.GET)
    public ResponseResult<?> queryAllCluster() {
    	List<String> list=new ArrayList<String>();
    	list.add("BIZ");
    	list.add("TEC");
    	list.add("OPS");
    	list.add("DATA");
    	list.add("IT");
    	return new ResponseResult(list);
    }
   
    /**
     * 功能描述: <br>
     * 新增
     *
     * @param host
     * @return
     */
    @RequestMapping(value = "/insert", method = RequestMethod.POST)
    public ResponseResult<?> insert(@RequestBody Host host) {
		Assert.hasText(host.getHostName(), "hostName不能为空");

    	Host hostParam=new Host();
    	hostParam.setHostName(host.getHostName());
    	hostParam.setDelStatus(0);
		int count = hostService.selectCount(hostParam);
		if(count>0){
			return new ResponseResult<>(ErrorCodeEnum.ERROR_COMMON_PARAM.getCode(), "host："+host.getHostName()+"已存在！");
		}
    	
    	host.setCreateTime(new Date());
    	host.setCreator(SsoHelper.currentUser().getNickname());
    	host.setMinionStatus(1);
    	hostService.insertSelective(host);
    	return new ResponseResult();
    }
    
    /**
     * 功能描述: <br>
     * 更新
     *
     * @param host
     * @return
     */
    @RequestMapping(value = "/update", method = RequestMethod.PUT)
    public ResponseResult<?> update(@RequestBody Host host) {
		Assert.hasText(host.getHostName(), "hostName不能为空");

    	host.setUpdateTime(new Date());
    	host.setUpdator(SsoHelper.currentUser().getNickname());
    	hostService.updateSelectiveById(host);
    	return new ResponseResult();
    }
    
    /**
     * 功能描述: <br>
     * 删除
     *
     * @param host
     * @return
     */
    @RequestMapping(value = "/delete", method = RequestMethod.DELETE)
    public ResponseResult<?> delete(@RequestBody Host host) {
    	host.setUpdateTime(new Date());
    	host.setUpdator(SsoHelper.currentUser().getNickname());
    	host.setDelStatus(1);
    	host.setId(host.getId());
    	hostService.updateSelectiveById(host);
    	return new ResponseResult();
    }
    
}
